package tp.pr5.instructions;

import tp.pr5.Constants;
import tp.pr5.NavigationModule;
import tp.pr5.RobotEngine;
import tp.pr5.instructions.exceptions.InstructionExecutionException;
import tp.pr5.instructions.exceptions.WrongInstructionFormatException;
import tp.pr5.items.Item;
import tp.pr5.items.ItemContainer;

/**
 * This instruction drops an Item from the current place and puts it the robot inventory. This instruction works if the user writes DROP or SOLTAR
 */
public class DropInstruction implements Instruction {
	private NavigationModule navigation;
	private RobotEngine robot;
	private ItemContainer robotContainer;
	private String id;
	
	/**
	 * It builds a default DropInstruction
	 */
	public DropInstruction()
	{
	}
	/**
	 * It builds a drop instruction with item name equals to the input parameter
	 * @param id The name of the item
	 */
	public DropInstruction(String id)
	{
		this.id = id;
	}
	
	@Override
	/**
	 * Parses the String returning an instance of DropInstruction or throwing a WrongInstructionFormatException()
	 * @param cad text String to parse
	 * @return Instruction Reference to an instance of DropInstruction
	 * @throws WrongInstructionFormatException - When the String is not 
	 */
	public Instruction parse(String cad) throws WrongInstructionFormatException {
		String[] commands;
		commands = cad.split(" ");
		
		if (commands[0].equalsIgnoreCase("DROP") || commands[0].equalsIgnoreCase("SOLTAR"))
		{
			if (commands.length >= 2)
			{
				return new DropInstruction (commands[1]);
			}
			else
				throw new WrongInstructionFormatException();
		}
		else
			throw new WrongInstructionFormatException();

	}

	@Override
	/**
	 * Instruction help
	 * @return the instruction syntax DROP <id>
	 */
	public String getHelp() {
		return "DROP|SOLTAR <id>";
	}

	@Override
	/**
	 * Fixes the current context, i.e., the robot engine and the navigation module
	 * @param engine - The robot engine
	 * @param navigation - The information about the game, i.e., the places, current direction and current heading to navigate
	 * @param robotContainer - The inventory of the robot
	 */
	public void configureContext(RobotEngine engine, NavigationModule navigation, ItemContainer robotContainer) {
		this.navigation = navigation;
		this.robotContainer = robotContainer;
		this.robot = engine;
	}

	@Override
	/**
	 * The robot drops an Item from its inventory in the current place, if the item exists
	 * @throws InstructionExecutionException - When the robot inventory does not contain an item with this name or when there is another item with the same id in the current place
	 */
	public void execute() throws InstructionExecutionException {
		try
		{
			Item item = this.robotContainer.pickItem(this.id);
			if(item != null)
			{
				if(navigation.findItemAtCurrentPlace(this.id))
				{
					this.robot.saySomething(Constants.MESSAGE_SAYS + Constants.MESSAGE_DROP_ERROR + this.id + Constants.LINE_SEPARATOR);
					throw new InstructionExecutionException();
				}
				else 
				{
					this.navigation.dropItemAtCurrentPlace(item);
					this.robot.saySomething(Constants.MESSAGE_SAYS + Constants.MESSAGE_DROP_OK + this.id + Constants.LINE_SEPARATOR);
				}
			}
			else
			{
				throw new InstructionExecutionException(Constants.MESSAGE_DROP_ERROR2 + this.id +".");
			}
			
		} catch(Exception e){
			throw new InstructionExecutionException(Constants.MESSAGE_DROP_ERROR2 + this.id +".");
		}
	}
}
